《Android 基础(五)》MVVM

介绍

MVVM,Model-View-ViewModel,与上次讲的MVP模式比较的类似,MVP中需要大量的接口文件,而MVVM模式下,View和ViewModel直接关联,使用上比较方便,简化了代码.大致的结构图如下:
这里写图片描述
可以看待View和ViewModel是双向的交互,这一点很关键

DataBinding

Data Binding Library是Google推出的,可以说是针对MVVM模式的支持库,通过在Layout中进行数据的访问,来实现View和Data的双向绑定。不仅使用灵活,用法丰富,而且支持也是相当的广泛,很大程度上降低了代码量和耦合性,减少了开发者的压力。

build.gradle

1
2
3
dataBinding {
enabled= true
}

这样使用比较的方法,当然这个需要当前的Gradle版本支持这个属性

Layout Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.example.mraz.mvvmdemo.Model.User"></import>
<variable
name="user"
type="User">
</variable>
</data>
<LinearLayout ...
</LinearLayout>
</layout>

最完成使用Layout属性,通过data属性值,添加需要在布局文件中使用的变量和对应的变量类型,也可以先import文件,然后直接使用,不然就需要在type中使用类型的完整路径,当遇到相同的类名的时候,DataBinding支持别名的定义,alias

Layout Access Data

布局文件文件中如何实现对绑定数据的访问

1
2
3
4
5
6
7
8
9
10
11
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.getUsername()}" />

<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.getPassword()}" />

使用格式为“@{ }”,大括号中的使用方式与代码中的基本无差别,可以使用方法,也可以使用对应的成员变量,当然如果权限允许的话,如果要直接访问private变量或者方法,显然是不现实的。

Activity Set Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MainActivity extends AppCompatActivity {
User user = new User("", "");
@Bind(R.id.et_username)
EditText etUsername;
@Bind(R.id.et_password)
EditText etPassword;
@Bind(R.id.tv_username)
TextView tvUsername;
@Bind(R.id.tv_password)
TextView tvPassword;

ActivityMainBinding activityMainBinding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
ButterKnife.bind(this);
}

@OnTextChanged(value = R.id.et_username, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onUserNameChanged(CharSequence s,int start,int before,int count) {
user.setUsername(s.toString());
activityMainBinding.setUser(user);
}

@OnTextChanged(value = R.id.et_password, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onPasswordChangedps(CharSequence s,int start,int before,int count) {
user.setPassword(s.toString());
activityMainBinding.setUser(user);
}

}

几个关键点:

  • ActivityMainBinding activityMainBinding
    这里定义的变量类型ActivityMainBinding 与布局文件对应
    activity_main ——-> ActivityMainBinding
    first_second ——-> FirstSecondingBinding
    Binding类的命名是基于所述layout文件的名称,用大写开头,除去下划线()以及()后的第一个字母大写,然后添加“Binding”后缀。这个类将被放置在一个模块封装包里的databinding封装包下 Binding类可通过调整data元素中的class属性来重命名或放置在不同的包中。例如:
1
2
3
<data class="UserBinding">
...
</data>
  • activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    获取ActivityMainBinding对象,用于后面设置变量
    activityMainBinding.setUser(user);设置数据,User变量

表达式

常用的表达式和正常的java代码比较类似

  • 数学 + - / * %
  • 字符串连接 +;
  • 逻辑 && ||
  • 二进制 & | ^
  • 一元运算 + - ! ~
  • 移位 >> >>> <<
  • 比较 == > < >= <=
  • instanceof
  • 分组 ()
    • null
  • Cast
  • 方法调用
  • 数据访问 []
  • 三元运算 ?:

不支持的操作

this
super
new
显式泛型调用

实际效果图

这里写图片描述

备注:
关于DataBinding,这里有一篇文章讲得很清晰,推荐一下
https://segmentfault.com/a/1190000002876984

效果图对应的代码贴了一部分,实现相对比较容易,这里就不赘述了,如果有需要的留言,我再附上。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×